import dayjs from "dayjs";
import { permissionGet } from '@/hooks/usePermission/index';
import { accredit } from '@/hooks/useAppPermission/index';
/**
 * 时间格式化
 * @param datetime Date | string | number | null，默认空值表示当前时间
 * @returns {*} { date, get, format, daysInMonth, weekday, unix }
 * @description date[Date]
 * @description get[function]：year(年)、month(月1-12)、day(日)、weekday(周日-0~周六-6)、hour(时)、hour-12(12小时制)、minute(分)、second(秒)、millisecond(毫秒)
 * @description format[function]：格式化，默认为YYYY-MM-DD HH:mm:ss，如：1999-01-02 03:04:05:006，YYYY-1999、YY-99、MM-01、M-1、DD-02、D-2、HH-03、H-3、mm-04、m-4、ss-05、s-5、S-006
 * @description daysInMonth[function]：当月有多少天
 * @description unix[function]：时间戳(10位)
 * @description getTime[function]：毫秒数
 */
export const formatTime = (datetime ?: Date | string | number | null) => {
	let date : Date = new Date()
	if (datetime) {
		if (datetime instanceof Date) {
			date = datetime
		} else if (typeof datetime === 'number') {
			date = new Date(Number(datetime.toString().padEnd(13, '0')))
		} else if (typeof datetime === 'string') {
			// ios解析不出YYYY-MM这种格式
			if (datetime.length < 8) datetime = `${datetime}-01`
			date = new Date(datetime.replace('T', ' ').replace(/-/g, '/'))
		}
	}
	const get = (
		value :
			| 'year'
			| 'month'
			| 'day'
			| 'weekday'
			| 'hour'
			| 'hour-12'
			| 'minute'
			| 'second'
			| 'millisecond'
	) => {
		switch (value) {
			case 'year':
				return date.getFullYear()
			case 'month':
				return date.getMonth() + 1
			case 'day':
				return date.getDate()
			case 'weekday':
				return date.getDay()
			case 'hour':
				return date.getHours()
			case 'hour-12':
				return date.getHours() > 12 ? date.getHours() - 12 : date.getHours()
			case 'minute':
				return date.getMinutes()
			case 'second':
				return date.getSeconds()
			case 'millisecond':
				return date.getMilliseconds()
		}
	}
	const format = (pattern : string = 'YYYY-MM-DD HH:mm:ss') => {
		const res : string[] = []
		const list =
			pattern.match(/YY(YY)?|yy(yy)?|MM?|DD?|HH?|hh?|mm?|ss?|S|./g) || []
		for (let i = 0; i < list.length; i++) {
			const value = list[i]
			switch (value) {
				case 'YYYY':
				case 'YY':
					res.push(
						value.length === 2
							? get('year').toString().substring(2, 4)
							: get('year').toString()
					)
					break
				case 'MM':
				case 'M':
					res.push(get('month').toString().padStart(value.length, '0'))
					break
				case 'DD':
				case 'D':
					res.push(get('day').toString().padStart(value.length, '0'))
					break
				case 'HH':
				case 'H':
					res.push(get('hour').toString().padStart(value.length, '0'))
					break
				case 'hh':
				case 'h':
					res.push(get('hour-12').toString().padStart(value.length, '0'))
					break
				case 'mm':
				case 'm':
					res.push(get('minute').toString().padStart(value.length, '0'))
					break
				case 'ss':
				case 's':
					res.push(get('second').toString().padStart(value.length, '0'))
					break
				case 'S':
					res.push(get('millisecond').toString())
					break
				default:
					res.push(value)
			}
		}
		return res.join('')
	}
	const daysInMonth = () => {
		return new Date(get('year'), get('month'), 0).getDate()
	}
	const unix = () => {
		return Math.round(date.getTime() / 1000)
	}
	const getTime = () => {
		return date.getTime()
	}
	const timeDifference = (curTime:any,endTime:any,arr?)=>{
		const start = curTime.getTime();
		const end = new Date(endTime).getTime();
		let leave = (end - start) / 1000;
		let timeSeconds = Math.floor(leave)
		const day = Math.floor(leave / 86400);
		leave = leave % 86400;
		let hour = Math.floor(leave / 3600)<10?"0"+Math.floor(leave / 3600):Math.floor(leave / 3600);
		leave = leave % 3600;
		var minute = Math.floor(leave / 60)<10?"0" + Math.floor(leave / 60) : Math.floor(leave / 60);
		leave = leave % 60;
		var seconds = Number(leave.toFixed(0))>10 && Number(leave.toFixed(0)) >=0 ?leave.toFixed(0):"0"+
		leave.toFixed(0);
		var result = null;
		if(timeSeconds <= 0){
			result = 0
		}else{
			result =  (day>0?(day + '天'):'') +
			(Number(hour)>0?(hour + '时'):'00时') + 
			(Number(minute)>0?(minute + '分'):'00分') + 
			(seconds + '秒')
		}
		if(arr){
			return [day ,hour , minute , seconds]
		}
		return result
	}
	return {
		date,
		get,
		format,
		daysInMonth,
		unix,
		getTime,
		timeDifference
	}
}

/**
 * 随机整数
 * @param min 最小数
 * @param max 最大数
 * @returns 随机数
 */
export const rand = (min : number, max : number) => {
	return Math.round(Math.random() * (max - min) + min)
}

/**
 * 防抖动
 * @description 持续触发事件时，只执行一次
 */
export const debounce = (delay = 500) => {
	let disabled = false
	let timer : ReturnType<typeof setTimeout> | null = null
	return (callback : () => void) => {
		if (!disabled) {
			callback && callback()
			disabled = true

		} else {
			uni.showToast({
				title: '请勿重复操作',
				icon: 'none'
			})
			if (timer) clearTimeout(timer)
		}
		timer = setTimeout(() => {
			disabled = false
		}, delay)
	}
}

/**
 * 节流
 * @description 持续触发事件时，隔一段时间执行一次
 */
export const throttle = (delay = 500) => {
	let disabled = false
	return (callback : () => void) => {
		if (!disabled) {
			callback && callback()
			disabled = true
			setTimeout(() => {
				disabled = false
			}, delay)
		}
	}
}

/**
 * 深克隆
 */
export const deepClone = (value : any) : any => {
	if (Array.isArray(value)) {
		const arr : any[] = []
		for (let i = 0; i < value.length; i++) {
			arr[i] = deepClone(value[i])
		}
		return arr
	} else if (
		typeof value === 'object' &&
		!(value instanceof Date) &&
		value !== null
	) {
		const obj : { [key : string] : any } = {}
		for (const k in value) {
			obj[k] = deepClone(value[k])
		}
		return obj
	}
	return value
}

/**
 * 判断两个值是否相等（包括对象）
 */
export const equals = (value1 : any, value2 : any) : boolean => {
	const isObject = (value : any) => typeof value === 'object' && value !== null
	if (!isObject(value1) || !isObject(value2)) return Object.is(value1, value2)
	else if (value1 === value2) return true
	const keys1 = Object.keys(value1)
	const keys2 = Object.keys(value2)
	if (keys1.length !== keys2.length) return false
	for (const key of keys1) {
		if (!keys2.includes(key)) return false
		const res = equals(value1[key], value2[key])
		if (!res) return false
	}
	return true
}

/*
* 根据出生日期计算年龄
* */

export const birthToAgeDiff = (birthDay : any = '') => {
	const birth = dayjs(birthDay);
	const now = dayjs();
	if (birth.valueOf() > now.valueOf()) return '未出生~'

	let years = now.year() - birth.year();
	let months = now.month() - birth.month();
	let days = now.date() - birth.date();

	if (days < 0) {
		months -= 1;
		days += dayjs(now).subtract(1, 'month').daysInMonth();
	}
	if (months < 0) {
		years -= 1;
		months += 12;
	}
	if (years > 0) {
		if (months > 0)
			return `${years}岁${months}个月`
		else
			return `${years}岁`
	} else {
		if (months > 0)
			return `${months}个月`
		else
			return `${days}天`
	}
};


export const dealHtml = (str) => {
	str = str.replace(
		/(\<img|\<video|\<iframe|\<\/iframe>|\<p)/gi,
		function ($0, $1) {
			return {
				'<img': '<img class="img" ref="img" mode="aspectFit" style="width:100%;height:auto;display:flex;" ',
				'<video': '<video style="width:100%;height:auto;" ',
				'<iframe': '<video style="width:100%;outline:none;"',
				'</iframe>': '</video>',
				'<p': '<p style="margin:0;"'
			}[$1];
		});
	return str
}

export const getLocation = () => {
	return new Promise(async(resolve, reject) => {
		console.log('判断定位权限')
		// #ifndef APP
		await permissionGet({
			code:"scope.userLocation"
		});
		// #endif
		// #ifdef APP
		const status = await accredit('ACCESS_FINE_LOCATION')
		if (status != 1) return
		// #endif
		
		uni.getLocation({
			type: 'gcj02',
			success: (res)=> {
				console.log('定位成功',res)
				resolve(res)
			},
			fail : (err)=> {
				console.log('定位失败',err)
				resolve(false)
			}
		});
		// resolve({
		// 	longitude:"114.3215",
		// 	latitude:"30.5674"
		// })
	})
}